package com.rxt.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.rxt.component.DelayMessageProducer;
import com.rxt.mapper.OOrdersDetailMapper;
import com.rxt.mapper.OShoppingCartMapper;
import com.rxt.mapper.PProductMapper;
import com.rxt.model.domain.OOrders;
import com.rxt.mapper.OOrdersMapper;
import com.rxt.model.domain.OOrdersDetail;
import com.rxt.model.domain.OShoppingCart;
import com.rxt.model.domain.PProduct;
import com.rxt.model.dto.UUserDto;
import com.rxt.model.vo.MyOrderVo;
import com.rxt.model.vo.OrderDetailVo;
import com.rxt.model.vo.PayForVo;
import com.rxt.model.vo.SaleOrderVo;
import com.rxt.service.IOOrdersService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rxt.util.BaseContext;
import com.rxt.util.UUIDUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 周梓文
 * @since 2023-08-24
 */
@Slf4j
@Service
public class OOrdersServiceImpl extends ServiceImpl<OOrdersMapper, OOrders> implements IOOrdersService {

    @Autowired
    private OShoppingCartMapper shoppingCartMapper;

    @Autowired
    private OOrdersMapper ordersMapper;

    @Autowired
    private OOrdersDetailMapper ordersDetailMapper;

    @Autowired
    private PProductMapper productMapper;

    @Autowired  // 注入生产者
    private DelayMessageProducer producer;

    @Value("${order.delay.time}")
    private Integer orderDelayTime;

    @Override
    public List<String> generatedOrder(Long addrId, List<OrderDetailVo> orderDetailVos) {
        UUserDto userDto = BaseContext.get();
        List<String> orderIdList = new ArrayList<>();
        for (OrderDetailVo orderDetailVo : orderDetailVos) {
            OOrders orders = new OOrders();
            orders.setOrdersId(UUIDUtils.getUUID16());
            orders.setStatus(1);
            orders.setUserId(userDto.getId());
            orders.setAddressBookId(addrId);
            orders.setOrderTime(LocalDateTime.now());
            orderIdList.add(orders.getOrdersId());
            ordersMapper.insert(orders);
            LambdaQueryWrapper<OShoppingCart> shoppingCartLambdaQueryWrapper = new LambdaQueryWrapper<>();
            shoppingCartLambdaQueryWrapper.eq(OShoppingCart::getUserId,userDto.getId())
                    .eq(OShoppingCart::getProductId,orderDetailVo.getProductId())
                    .eq(OShoppingCart::getSkuId,orderDetailVo.getSkuId());
            OShoppingCart shoppingCart = shoppingCartMapper.selectOne(shoppingCartLambdaQueryWrapper);
            OOrdersDetail ordersDetail = new OOrdersDetail();
            BeanUtils.copyProperties(shoppingCart,ordersDetail);
            ordersDetail.setCreateTime(LocalDateTime.now());
            ordersDetail.setUpdateTime(LocalDateTime.now());
            ordersDetail.setOrderId(orders.getId());
            ordersDetailMapper.insert(ordersDetail);
            shoppingCartMapper.deleteById(shoppingCart.getId());

            // 添加到MQ
            producer.send(orders.getId()+"", orderDelayTime);

        }
        return orderIdList;
    }

    @Override
    public void payFor(PayForVo payForVo) {
        for (String orderIdList : payForVo.getOrderIdList()) {
            LambdaUpdateWrapper<OOrders> wrapper = new LambdaUpdateWrapper<>();
            wrapper.eq(OOrders::getOrdersId,orderIdList)
                    .set(OOrders::getStatus,2)
                    .set(OOrders::getCheckoutTime,LocalDateTime.now())
                    .set(OOrders::getPayMethod,payForVo.getPayMethod());
            ordersMapper.update(null,wrapper);
        }
    }

    @Override
    public List<OOrdersDetail> getOrders(List<String> orderIds) {
        List<OOrdersDetail> ordersDetails = new ArrayList<>();
        for (String orderId : orderIds) {
            LambdaQueryWrapper<OOrders> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(OOrders::getOrdersId,orderId);
            OOrders orders = ordersMapper.selectOne(wrapper);
            LambdaQueryWrapper<OOrdersDetail> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(OOrdersDetail::getOrderId,orders.getId());
            ordersDetails.add(ordersDetailMapper.selectOne(queryWrapper));
        }
        return ordersDetails;
    }

    @Override
    public List<SaleOrderVo> getSaleOrder() {
        UUserDto userDto = BaseContext.get();
        LambdaQueryWrapper<PProduct> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PProduct::getUserId,userDto.getId());
        List<PProduct> products = productMapper.selectList(wrapper);
        if (products.size() == 0) {
            return null;
        }
        List<SaleOrderVo> saleOrderVos = new ArrayList<>();
        List<OOrdersDetail> ordersDetails = new ArrayList<>();
        for (PProduct product : products) {
            LambdaQueryWrapper<OOrdersDetail> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(OOrdersDetail::getProductId,product.getId());
            List<OOrdersDetail> ordersDetail = ordersDetailMapper.selectList(wrapper1);
            ordersDetails.addAll(ordersDetail);
        }
        for (OOrdersDetail ordersDetail : ordersDetails) {
            LambdaQueryWrapper<OOrders> wrapper2 = new LambdaQueryWrapper<>();
            wrapper2.eq(OOrders::getId,ordersDetail.getOrderId());
            OOrders order = ordersMapper.selectOne(wrapper2);
            SaleOrderVo saleOrderVo = new SaleOrderVo();
            saleOrderVo.setId(order.getId());
            saleOrderVo.setOrderId(order.getOrdersId());
            saleOrderVo.setStatus(order.getStatus());
            saleOrderVo.setCheckoutTime(order.getCheckoutTime());
            saleOrderVo.setImage(ordersDetail.getImage());
            saleOrderVo.setProductName(ordersDetail.getProductName());
            saleOrderVos.add(saleOrderVo);
        }
        Collections.sort(saleOrderVos);
        return saleOrderVos;
    }

    @Override
    public SaleOrderVo getOrderById(String orderId) {
        LambdaQueryWrapper<OOrders> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OOrders::getOrdersId,orderId);
        OOrders order = ordersMapper.selectOne(wrapper);
        SaleOrderVo saleOrderVo = new SaleOrderVo();
        saleOrderVo.setId(order.getId());
        saleOrderVo.setOrderId(order.getOrdersId());
        saleOrderVo.setStatus(order.getStatus());
        saleOrderVo.setCheckoutTime(order.getCheckoutTime());
        LambdaQueryWrapper<OOrdersDetail> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(OOrdersDetail::getOrderId,order.getId());
        OOrdersDetail ordersDetail = ordersDetailMapper.selectOne(wrapper1);
        saleOrderVo.setImage(ordersDetail.getImage());
        saleOrderVo.setProductName(ordersDetail.getProductName());
        return saleOrderVo;
    }

    @Override
    public void changeStatus(String orderId) {
        LambdaUpdateWrapper<OOrders> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(OOrders::getOrdersId,orderId)
                .set(OOrders::getStatus,3);
        ordersMapper.update(null,wrapper);
    }

    @Override
    public List<MyOrderVo> getMyOrder(Integer status) {
        UUserDto userDto = BaseContext.get();
        LambdaQueryWrapper<OOrders> wrapper = new LambdaQueryWrapper<>();
        if (status == 0) {
            wrapper.eq(OOrders::getUserId,userDto.getId());
        }else {
            wrapper.eq(OOrders::getUserId,userDto.getId())
                    .eq(OOrders::getStatus,status);
        }
        List<OOrders> orders = ordersMapper.selectList(wrapper);
        List<MyOrderVo> myOrderVos = new ArrayList<>();
        for (OOrders order : orders) {
            MyOrderVo myOrderVo = new MyOrderVo();
            myOrderVo.setId(order.getId());
            myOrderVo.setOrdersId(order.getOrdersId());
            myOrderVo.setStatus(order.getStatus());
            myOrderVo.setCheckoutTime(order.getCheckoutTime());
            LambdaQueryWrapper<OOrdersDetail> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(OOrdersDetail::getOrderId,order.getId());
            OOrdersDetail ordersDetail = ordersDetailMapper.selectOne(wrapper1);
            myOrderVo.setImage(ordersDetail.getImage());
            myOrderVo.setPrice(ordersDetail.getPrice());
            myOrderVo.setAddressId(order.getAddressBookId());
            myOrderVo.setProductName(ordersDetail.getProductName());
            myOrderVo.setProductSku(ordersDetail.getProductSku());
            myOrderVo.setNumber(ordersDetail.getNumber());
            myOrderVo.setAmount(ordersDetail.getAmount());
            myOrderVos.add(myOrderVo);
        }
        Collections.sort(myOrderVos);
        return myOrderVos;
    }

    @Override
    public void confirmReceipt(Long id) {
        LambdaUpdateWrapper<OOrders> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(OOrders::getId,id)
                .set(OOrders::getStatus,4);
        ordersMapper.update(null,wrapper);
    }


}
